package org.yzhzc.friend.manager;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.yzhzc.common.core.constants.CacheConstants;
import org.yzhzc.common.core.enums.ResultCode;
import org.yzhzc.common.redis.service.RedisService;
import org.yzhzc.common.security.exception.ServiceException;
import org.yzhzc.friend.domain.question.entity.Question;
import org.yzhzc.friend.mapper.question.QuestionMapper;

import java.util.List;

/**
 * 题目缓存管理类。
 * 负责管理题目列表和热门题目列表的缓存操作，包括刷新缓存、获取题目列表大小、导航题目等。
 */
@Component
public class QuestionCacheManager {

    @Autowired
    private RedisService redisService; // Redis 服务接口

    @Autowired
    private QuestionMapper questionMapper; // 题目数据访问接口

    /**
     * 获取题目列表的大小。
     *
     * @return 题目列表的大小
     */
    public Long getListSize() {
        return redisService.getListSize(CacheConstants.QUESTION_LIST);
    }

    /**
     * 获取热门题目列表的大小。
     *
     * @return 热门题目列表的大小
     */
    public Long getHostListSize() {
        return redisService.getListSize(CacheConstants.QUESTION_HOST_LIST);
    }

    /**
     * 刷新题目列表缓存。
     * 从数据库中查询最新的题目ID列表，并更新到 Redis 缓存中。
     */
    public void refreshCache() {
        // 从数据库中查询题目ID列表，按创建时间降序排序
        List<Question> questionList = questionMapper.selectList(new LambdaQueryWrapper<Question>()
                .select(Question::getQuestionId).orderByDesc(Question::getCreateTime));

        // 如果查询结果为空，直接返回
        if (CollectionUtil.isEmpty(questionList)) {
            return;
        }

        // 提取题目ID列表
        List<Long> questionIdList = questionList.stream().map(Question::getQuestionId).toList();

        // 将题目ID列表存入 Redis 缓存
        redisService.rightPushAll(CacheConstants.QUESTION_LIST, questionIdList);
    }

    /**
     * 获取当前题目的上一个题目ID。
     *
     * @param questionId 当前题目ID
     * @return 上一个题目ID
     * @throws ServiceException 如果当前题目是第一个题目，抛出异常
     */
    public Long preQuestion(Long questionId) {
        // 获取当前题目在列表中的索引
        Long index = redisService.indexOfForList(CacheConstants.QUESTION_LIST, questionId);

        // 如果当前题目是第一个题目，抛出异常
        if (index == 0) {
            throw new ServiceException(ResultCode.FAILED_FIRST_QUESTION);
        }

        // 返回上一个题目ID
        return redisService.indexForList(CacheConstants.QUESTION_LIST, index - 1, Long.class);
    }

    /**
     * 获取当前题目的下一个题目ID。
     *
     * @param questionId 当前题目ID
     * @return 下一个题目ID
     * @throws ServiceException 如果当前题目是最后一个题目，抛出异常
     */
    public Object nextQuestion(Long questionId) {
        // 获取当前题目在列表中的索引
        Long index = redisService.indexOfForList(CacheConstants.QUESTION_LIST, questionId);

        // 获取题目列表的最后一个索引
        long lastIndex = getListSize() - 1;

        // 如果当前题目是最后一个题目，抛出异常
        if (index == lastIndex) {
            throw new ServiceException(ResultCode.FAILED_LAST_QUESTION);
        }

        // 返回下一个题目ID
        return redisService.indexForList(CacheConstants.QUESTION_LIST, index + 1, Long.class);
    }

    /**
     * 获取热门题目列表。
     *
     * @return 热门题目的ID列表
     */
    public List<Long> getHostList() {
        return redisService.getCacheListByRange(CacheConstants.QUESTION_HOST_LIST,
                CacheConstants.DEFAULT_START, CacheConstants.DEFAULT_END, Long.class);
    }

    /**
     * 刷新热门题目列表缓存。
     *
     * @param hotQuestionIdList 热门题目的ID列表
     */
    public void refreshHotQuestionList(List<Long> hotQuestionIdList) {
        // 如果热门题目列表为空，直接返回
        if (CollectionUtil.isEmpty(hotQuestionIdList)) {
            return;
        }

        // 将热门题目ID列表存入 Redis 缓存
        redisService.rightPushAll(CacheConstants.QUESTION_HOST_LIST, hotQuestionIdList);
    }
}
